package com.example.xuzhaoyu.hotfixdemo;

import android.content.Context;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.os.Environment;
import android.util.Log;


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.security.MessageDigest;


public class FileUtil {
    private static final String TAG = FileUtil.class.getSimpleName();
    private static Context context;

    public FileUtil(Context context) {
        FileUtil.context = context.getApplicationContext();
    }

    /* Checks if external storage is available for read and write */
    public static boolean isExternalStorageWritable() {
        String state = Environment.getExternalStorageState();
        return Environment.MEDIA_MOUNTED.equals(state);
    }

    /**
     * @param inputStream
     * @param filepath
     */
    public static void saveFile(InputStream inputStream, String filepath) {
        if (!isExternalStorageWritable()) {
            return;
        }
        File file = new File(filepath);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            byte[] buffer = new byte[1024];
            int cnt = 0;
            while ((cnt = inputStream.read(buffer)) != -1) {
                fos.write(buffer, 0, cnt);
            }
            inputStream.close();
            fos.close();
        } catch (IOException e) {
            Log.i(TAG, e.getMessage());
        }
    }

    /**
     * Copy file
     *
     * @param from origin file path
     * @param to   target file path
     */
    public static boolean copyFile(String from, String to) {
        if (!isExternalStorageWritable()) {
            return false;
        }
        File fileFrom = new File(from);
        File fileTo = new File(to);
        try {
            FileInputStream fis = new FileInputStream(fileFrom);
            FileOutputStream fos = new FileOutputStream(fileTo);
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
            fis.close();
            fos.close();
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @param json
     * @param filepath
     */
    public static boolean saveJson(String json, String filepath) {
        if (!isExternalStorageWritable()) {
            return false;
        }
        File file = new File(filepath);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(json.getBytes());
            fos.close();
        } catch (FileNotFoundException e) {
            Log.i(TAG, e.getMessage());
        } catch (IOException e) {
            return false;
        }

        return true;
    }

    /**
     * @param filepath
     * @return
     */
    public static boolean deleteJson(String filepath) {
        if (!isExternalStorageWritable()) {
            return false;
        }
        File file = new File(filepath);
        if (file.exists()) {
            file.delete();
        }
        return false;
    }

    /**
     * @param filepath
     * @return
     */
    public static String readJson(String filepath) {
        if (!isExternalStorageWritable()) {
            return null;
        }
        File file = new File(filepath);
        StringBuilder sb = new StringBuilder();
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    new FileInputStream(file)));
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            reader.close();
        } catch (IOException e) {
            Log.i(TAG, e.getMessage());
        }
        return sb.toString();
    }

    /**
     * @param filepath
     * @param bitmap
     */
    public static void saveBitmap(String filepath, Bitmap bitmap) {
        if (!isExternalStorageWritable()) {
            return;
        }
        if (bitmap == null) {
            return;
        }
        try {
            File file = new File(filepath);
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
            fileOutputStream.flush();
            fileOutputStream.close();
        } catch (IOException e) {
            Log.i(TAG, e.getMessage());
        }
    }

    /**
     * @return
     */
    public static boolean cleanCache() {
        if (!isExternalStorageWritable()) {
            return false;
        }
        File dir = context.getExternalFilesDir(null);
        if (dir != null) {
            for (File file : dir.listFiles()) {
                file.delete();
            }
        }
        return true;
    }

    /**
     * @return
     */
    public static String getCacheSize() {
        if (!isExternalStorageWritable()) {
            return null;
        }
        long sum = 0;
        File dir = context.getExternalFilesDir(null);

        if (dir != null) {
            for (File file : dir.listFiles()) {
                sum += file.length();
            }
        }
        if (sum < 1024) {
            return sum + "B";
        } else if (sum < 1024 * 1024) {
            return (sum / 1024) + "K";
        } else {
            return (sum / (1024 * 1024)) + "M";
        }
    }

    /**
     * /storage/sdcard0/Android/data/com.example.test/files
     */
    public static String getAbsolutePath() {
        File root = context.getExternalFilesDir(null);
        if (root != null) {
            return root.getAbsolutePath();
        }
        return null;
    }

    public static String getCachePath() {
        File root = context.getExternalCacheDir();
        if (root != null) {
            return root.getAbsolutePath();
        }
        return null;
    }

    public static boolean isBitmapExists(String filename) {
        File dir = context.getExternalFilesDir(null);
        File file = new File(dir, filename);

        return file.exists();
    }

    public static String getMimeType(String filePath) {
        MediaMetadataRetriever mmr = new MediaMetadataRetriever();
        String mime = "text/plain";
        if (filePath != null) {
            try {
                mmr.setDataSource(filePath);
                mime = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE);
            } catch (RuntimeException e) {
                return mime;
            }
        }
        return mime;
    }

    public static long getFolderSize(File file) {
        long size = 0;
        try {
            File[] fileList = file.listFiles();
            for (File aFileList : fileList) {
                if (aFileList.isDirectory()) {
                    size = size + getFolderSize(aFileList);
                } else {
                    size = size + aFileList.length();

                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return size;
    }

    public static void deleteDir(String path) {
        try {
            File dir = new File(path);
            deleteDirWithFile(dir);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void deleteDirWithFile(File dir) {
        if (dir == null || !dir.exists() || !dir.isDirectory()) {
            return;
        }
        for (File file : dir.listFiles()) {
            if (file.isFile()) {
                file.delete(); // 删除所有文件
            } else if (file.isDirectory()) {
                deleteDirWithFile(file); // 递规的方式删除文件夹
            }
            dir.delete();// 删除目录本身
        }
    }

    public static String getFileMD5(File file) {
        if (!file.isFile()) {
            return null;
        }
        MessageDigest digest = null;
        FileInputStream inputStream = null;
        byte buffer[] = new byte[1024];
        int len;
        try {
            digest = MessageDigest.getInstance("MD5");
            inputStream = new FileInputStream(file);
            while ((len = inputStream.read(buffer, 0, 1024)) != -1) {
                digest.update(buffer, 0, len);
            }
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        BigInteger bigInt = new BigInteger(1, digest.digest());
        return bigInt.toString(16);
    }
}
